package cn.wolfcode.util;

import cn.wolfcode.domain.SystemLog;
import cn.wolfcode.service.ISystemLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Enumeration;

@Component //把当前类注入到spring容器中
@Aspect    //把当前类标识为一个切面供容器读取
public class AopConfig {

    @Autowired
    private ISystemLogService systemLogService;
    /**
     * 指定切入点
     * 对贴有自定义注解@RequiredPermission的方法，进行切面
     */
    @Pointcut("@annotation(cn.wolfcode.util.RequiredPermission)")
    private void useMethod() {}

    /**
     * 对切入点进行增强
     */
    @Around(value = "useMethod()")
    public Object recordLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //创建日志对象
        SystemLog systemLog = new SystemLog();
        //方法开始时间
        long startDate = System.currentTimeMillis();
        //设置操作人
        systemLog.setEmployeeName(UserContextUtil.getCurrentEmployee().getName());
        //操作时间
        systemLog.setOperationTime(new Date());
        //调用父类方法
        Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
        //获取权限注解
        RequiredPermission annotation = method.getAnnotation(RequiredPermission.class);
        if(annotation != null){
            //操作方法
            systemLog.setPermissionName(annotation.name());
            //操作权限
            systemLog.setPermissionExpression(annotation.expression());
        }
        //获取容器请求对象
        ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attrs.getRequest();
        //获取ip
        systemLog.setIp(request.getRemoteAddr());
        systemLog.setOperationResult(true);

        Enumeration<String> enu = request.getParameterNames();
        StringBuilder sb = new StringBuilder();
        while (enu.hasMoreElements()) {
            String name = (String) enu.nextElement();
            String code = new String(request.getParameter(name).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            sb.append(name).append("=").append(code).append("&");
        }
        //设置参数
        systemLog.setRequestCode(sb.toString());
        //systemLog.setRequestCode(request.getQueryString());
        Object result = null;
        try {
            //执行处理方法（执行控制器中的方法）
            result = proceedingJoinPoint.proceed();
        } catch (RuntimeException e) {
            systemLog.setOperationResult(false);
            systemLog.setErrorMessage(e.getMessage());
            throw new Exception(e.getMessage());
        }finally {
            //获取当前时间戳
            long endDate = System.currentTimeMillis();
            systemLog.setExecutionTime(endDate - startDate);
            systemLogService.save(systemLog);
        }
        //result是方法的返回值，直接return回去就会返回给springmvc处理
        return result;
    }
}